package com.study;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import java.io.IOException;
import java.util.List;

/**
 * @Description Redis6-Redis秒杀案例-Redis接口实现类
 * @auther jianghao
 * @date 2022-04-17
 */
public class SecKill_redis {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("82.157.183.197", 11079);
        System.out.println(jedis.ping());
        jedis.close();
    }

    //秒杀主方法--全过程
    public static boolean doSecKill(String uid, String prodid) throws IOException {
        //步骤1 根据入参用户ID-uid和商品ID-prodid 进行非空判断
        if (uid == null || prodid == null) {
            return false;
        }

        //步骤2 连接redis
        // Jedis jedis = new Jedis("82.157.183.197", 11079);

        // 步骤2 通过连接池得到jedis对象
        JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();
        Jedis jedis = jedisPoolInstance.getResource();

        //步骤3 拼接key
        // 3.1 库存key
        String kcKey = "sk:" + prodid + ":qt";
        // 3.2 秒杀成功的用户key
        String userKey = "sk:" + prodid + ":user";

        // 秒杀过程添加乐观锁事务管理 -- 监视库存
        jedis.watch(kcKey);

        // 步骤4 获取库存，如果库存null，秒杀还没有开始
        String kc = jedis.get(kcKey);
        if (kc == null) {
            System.out.println("秒杀还没有开始，请等待");
            jedis.close();
            return false;
        }

        // 步骤5 判断用户是否重复秒杀操作
        // 判断set集合中的用户信息，因为不能存在重复的用户【不能重复秒杀】所以使用Set存储用户信息
        if (jedis.sismember(userKey, uid)) {
            System.out.println("已经秒杀成功了，不能重复秒杀");
            jedis.close();
            return false;
        }

        // 步骤6 判断如果商品数量，库存数量小于1，秒杀结束
        if (Integer.parseInt(kc) <= 0) {
            System.out.println("秒杀已经结束了");
            jedis.close();
            return false;
        }

/*        // 步骤7 秒杀的过程
        //7.1 库存-1
        jedis.decr(kcKey);
        //7.2 把秒杀成功用户添加清单里面
        jedis.sadd(userKey, uid);*/

        //步骤7改造 秒杀过程添加乐观锁事务管理
        //使用事务
        Transaction multi = jedis.multi();

        //组队操作
        multi.decr(kcKey);
        multi.sadd(userKey,uid);

        //执行
        List<Object> results = multi.exec();

        if(results == null || results.size()==0) {
            System.out.println("秒杀失败了....");
            jedis.close();
            return false;
        }

        System.out.println("秒杀成功了..");
        jedis.close();
        return true;
    }
}
















